<!--
 * @Author: wfl
 * @LastEditors: '张朋朋' '14065467+a598001989@user.noreply.gitee.com'
 * @description:
 * @updateInfo:
 * @Date: 2022-05-05 16:49:41
 * @LastEditTime: 2024-04-17 10:27:53
-->
<script setup lang="ts">
import {  Ref, ref, toRaw } from 'vue'
import DataHeader from './components/data-header.vue'
import { connecting, dbApi } from '@/api/datebase'
import { useDialog, useMessage, NPagination } from 'naive-ui'
const nMessage = useMessage()
const dialog = useDialog()
const loading = ref(false)
const showModal = ref(false)
const formRef = ref(null)
const baseTypes = ref([
  { label: 'MYSQL', value: 'MYSQL' },
  { label: 'POSTGRES', value: 'POSTGRES' },
  { label: 'ORACLE', value: 'ORACLE' },
  { label: 'MSSQL_SERVER', value: 'MSSQL_SERVER' },
])
const sourceForm: Ref<{
  type: string | number
  serviceName:null|string
  name: string
  ip: string
  port: string
  username: string
  password: string
  id?: string
}> = ref({
  type: '',
  serviceName:null,
  name: '',
  ip: '',
  port: '3306',
  username: '',
  password: '',
})
// 验证
const rules = {
  name: [
    { required: true, trigger: 'blur', message: '请输入名称' },
  ],
  type: [
    { required: true, trigger: 'change', message: '请选择数据源' },
  ],
  serviceName: [
    { required: true, trigger: 'blur', message: '请输入服务名称' },
  ],
  ip:[
    { required: true, trigger: 'blur', message: '请输入数据库地址' },
  ],
  port:[
    { required: true, trigger: 'blur', message: '请输入数据库端口' },
  ],
  username:[
    { required: true, trigger: 'blur', message: '请输入用户名' },
  ],
  password:[
    { required: true, trigger: 'blur', message: '请输入密码' },
  ],
}

// 数据源列表
const sourceData = reactive({
  // 列表数据
  list:[],
  // 分页
  page:{
    page:1,
    total:0,
    size: 20,
  },
  // 获取列表数据
  getData:async ()=>{
    const res = await dbApi.queryDb({ page:sourceData.page.page, rows: sourceData.page.size })
    if (res.success) {
      sourceData.list = res?.data ?? []
    }
  },
  // 分页发生变化
  pageChange:(value:number)=>{
    sourceData.page.page = value
    sourceData.getData()
  },
  // 分页数发生变化
  sizeChange:(value:number)=>{
    sourceData.page.size = value
    sourceData.getData()
  },
})
sourceData.getData()

// 测试链接
const testConnection = reactive({
  loading:false,
  click: async ()=>{
    testConnection.loading = true
    const res = await connecting(toRaw(sourceForm.value))
    if (res?.success) {
      nMessage.success(res?.msg)
    } else {
      nMessage.error(res?.msg)
    }
    testConnection.loading = false
  },
})

// 关闭
const handCancel = () => {
  showModal.value = false
  loading.value = false
  sourceForm.value = {
    type: '',
    name: '',
    ip: '',
    port: '3306',
    username: '',
    password: '',
  }
}
// 提交
const handleConfirm = async () => {
  formRef.value?.validate(async (errors: any) => {
    if(!errors){
      loading.value = true
      const res = sourceForm.value.id
        ? await dbApi.updateDb(sourceForm.value)
        : await dbApi.addDb(sourceForm.value)
      if (res.success) {
        handCancel()
        sourceData.getData()
      }
      loading.value = false
    }
  })
}

// 删除
const handleClose = d => {
  dialog.warning({
    title: '警告',
    content: '你确定删除该数据源吗？',
    positiveText: '确定',
    negativeText: '取消',
    showIcon: false,
    onPositiveClick: async () => {
      const res = await dbApi.deleteDb(d.id)
      if (res?.success) {
        sourceData.getData()
      }
    },
  })
}
// 修改
const handEdit = d => {
  sourceForm.value = d
  showModal.value = true
}

</script>

<template>
  <div class="data-source">
    <DataHeader
      label="添加的数据源在当前登录用户所有大屏均可使用"
      @hand-click="showModal = true"
    />
    <div class="source-box">
    <div class="data-source-card">
      <n-card
        v-for="d in sourceData.list"
        :key="d.id"
        :hoverable="true"
        :title="d.name"
        closable
        @close="handleClose(d)"
      >
        <ul @click="handEdit(d)">
          <li>
            <b>{{ d.type }}</b>
          </li>
          <li>{{ d.ip }}</li>
          <li>{{ d.port }}</li>
          <li>{{ d.username }}</li>
          <li>{{ d.password.replace(/\S/g, "*") }}</li>
        </ul>
      </n-card>
    </div>
    </div>
    <div class="page-list">
      <n-pagination
        v-model:page="sourceData.page.page"
        :item-count="sourceData.page.total"
        :page-size="sourceData.page.size"
        size="medium"
        show-quick-jumper
        show-size-picker
        :page-sizes="[20, 30, 40, 50, 60]"
        @update:page="sourceData.pageChange"
        @update:page-size="sourceData.sizeChange"
      />
    </div>
  </div>

  <n-modal
    v-model:show="showModal"
    :mask-closable="false"
    preset="dialog"
    :show-icon="false"
    title="Dialog"
  >
    <template #header>
      <div>新增数据源配置</div>
    </template>
    <div>
      <n-form
        ref="formRef"
        :label-width="80"
        label-placement="top"
        :model="sourceForm"
        :rules="rules"
        size="small"
      >
        <n-form-item label="名称" path="name">
          <n-input v-model:value="sourceForm.name" placeholder="输入配置名称" />
        </n-form-item>
        <n-form-item label="数据源" path="type">
          <n-select v-model:value="sourceForm.type" :options="baseTypes" />
        </n-form-item>
        <n-form-item v-if="sourceForm.type==='ORACLE'" label="服务名称" path="serviceName">
          <n-input v-model:value="sourceForm.serviceName" placeholder="输入服务名称" />
        </n-form-item>
        <n-form-item label="地址" path="ip">
          <n-input v-model:value="sourceForm.ip" placeholder="输入数据库地址" />
        </n-form-item>
        <n-form-item label="端口" path="port">
          <n-input v-model:value="sourceForm.port" placeholder="输入数据库端口" />
        </n-form-item>
        <n-form-item label="用户名" path="username">
          <n-input v-model:value="sourceForm.username" placeholder="输入用户名" />
        </n-form-item>
        <n-form-item label="密码" path="password">
          <n-input
            v-model:value="sourceForm.password"
            type="password"
            placeholder="输入密码"
          />
          <n-button
            attr-type="button"
            :disabled="testConnection.loading"
            :loading="testConnection.loading"
            style="margin-left: 8px;"
            @click="testConnection.click"
          >
            测试连接
          </n-button>
        </n-form-item>
      </n-form>
    </div>
    <template #action>
      <n-button :disabled="loading" @click="handCancel">取消</n-button>
      <n-button type="primary" :disabled="loading" @click="handleConfirm"> 确定 </n-button>
    </template>
  </n-modal>
</template>

<style lang="scss" scoped>
.data-source {
  flex: 1;
  padding: 20px 28px 0;
  width: 100%;
  .source-box{
    height: calc(100vh - 180px);
    overflow-y: auto;
  }
  .data-source-card {
    display: grid;
    grid-template-columns: repeat(auto-fill, 300px);
    grid-gap: 15px;
    margin: 15px 0;
    grid-template-rows: 280px;
    .n-card {
      cursor: pointer;
      border-radius: 8px;
      box-shadow: 0 0 11px 2px #00000063;
      background: #17191c;

      &.n-card--bordered {
        border: none;
      }

      ul {
        line-height: 27px;
      }

      li:not(:last-child) {
        border-bottom: 1px solid rgb(95 95 95 / 9%);
        padding: 8px 0;
      }
    }
  }
}
.page-list{
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}
</style>
